home *** CD-ROM | disk | FTP | other *** search
/ Macwelt 1 / Macwelt DVD 1.toast / Web-Publishing / HTML-Editoren / Alpha ƒ / Tcl / Modes / javaMode.tcl < prev    next >
Encoding:
Text File  |  2001-01-05  |  12.7 KB  |  375 lines

  1. # (install)
  2.  
  3. alpha::mode Java 1.15 javaMenu {*.java *.j} {
  4.     javaMenu electricBraces electricSemicolon electricReturn
  5. } {
  6.     addMenu javaMenu "•140" Java
  7.     alpha::package require AlphaTcl 7.2.1b5
  8. } help {
  9.     Java Mode supplies a menu for easy switching between your favorite Java
  10.     compiler and Alpha (shift-cmd-S), will send a file to be compiled
  11.     (shift-cmd-K).  The Java Menu can be used to open a HTML file
  12.     corresponding to a java file in the Applet Viewer.  If there is a
  13.     file some_applet.html in the same folder as some_applet.java it is
  14.     sent.  Otherwise the user is asked to select a HTML file.  This file
  15.     is remembered throughout this session with Alpha.  Java Mode
  16.     provides keyword coloring and method marking with the Marks Menu;
  17.     relies on C++ Mode for its handling of automatic code indention.
  18.  
  19.     Click on this "Jave Example.java" link for an example syntax file.
  20. }
  21.  
  22. array set javacompilerAppSignatures {
  23.     Suncompiler javc
  24. }
  25. array set javacompilerAppScripts {
  26.     Suncompiler {
  27.     {sendOpenEvent -n $quotedSig $filename}
  28.     }
  29. }
  30.  
  31. # required for use of C++::correctIndentation
  32. newPref f useFasterButWorseIndentation 0 Java
  33. newPref v indentComments "code 0" Java "" indentationTypes varitem
  34. newPref v indentC++Comments "code 0" Java "" indentationTypes varitem
  35.  
  36. newPref    flag allowMultipleClassesPerFile 0 Java
  37. newPref    f elecColon {1} Java
  38. newPref    v leftFillColumn {3} Java
  39. newPref    v prefixString {//} Java 
  40. newPref    f wordWrap {0} Java
  41. newPref    v funcExpr {^[^ \t\(#\r/@].*\(.*\)$} Java
  42. newPref    v parseExpr {\b([_:\w]+)\s*\(} Java
  43. newPref v wordBreak {[\w_]+} Java
  44. newPref v wordBreakPreface {[^_\w]} Java
  45. newPref    f autoMark    0 Java
  46. # To synchronise Alpha's value for your java class path with the current
  47. # value in your system environment each time Alpha starts up, click this 
  48. # box||To let Alpha maintain its own value for your classpath independent
  49. # of the systemwide value, click this box.
  50. newPref    f classPathSynchroniseWithEnv    1 Java
  51. # Your Java class path.
  52. newPref v classSearchPath "" Java
  53. newPref    color stringColor    green Java
  54. newPref    color commentColor    red     Java
  55. newPref    color keywordColor    blue Java
  56. newPref color funcColor yellow Java
  57. newPref f includeMenu 1 Java
  58. newPref variable showJavacompilerLog 1 Java "" \
  59.   [list "Never" "Only after error" "Always"] index
  60.  
  61. ensureset Java_projectStore(placeClassesHere) ""
  62. ensureset Java_projectStore(compileFromThisFolder) ""
  63. ensureset JavaProjects(Usual) [array get Java_projectStore]
  64. ensureset JavaProject Usual
  65.  
  66. regModeKeywords     -e {//} -b {/*} {*/}    -c $JavamodeVars(commentColor) \
  67.          -f $JavamodeVars(funcColor) -k $JavamodeVars(keywordColor) \
  68.          -s $JavamodeVars(stringColor) Java {
  69.     abstract boolean break byte byvalue case catch char class const 
  70.     continue default do double else extends false final finally float for 
  71.     goto if implements import instanceof int interface long native new 
  72.     null package private protected public return short static super switch 
  73.     synchronized this throw throws transient true try void while future 
  74.     generic inner outer operator rest var volatile
  75. }
  76. regModeKeywords -a -k color_9 Java { Object String }
  77.  
  78. proc javaMenu {} {}
  79.  
  80. if {$JavamodeVars(classPathSynchroniseWithEnv)} {
  81.     if {[info exists env(CLASSPATH)]} {
  82.     set JavamodeVars(classSearchPath) [split $env(CLASSPATH) ";"]
  83.     }
  84. }
  85.  
  86. ## 
  87.  # -------------------------------------------------------------------------
  88.  # 
  89.  # "menu::buildjavaMenu" --
  90.  # 
  91.  #  Use a build proc so we can add things on the fly.
  92.  # -------------------------------------------------------------------------
  93.  ##
  94. proc Java::buildMenu {} {
  95.     global javaMenu
  96.     set ma {
  97.     "/S<U<OswitchToCompiler"
  98.     "(-"
  99.     "/K<U<OcompileFile"
  100.     "(-"
  101.     "/V<U<OviewApplet"
  102.     "//<BnewJavadocComment"
  103.     "editProjects"
  104.     }
  105.     return [list build $ma Java::MenuProc "" $javaMenu]
  106. }
  107. menu::buildProc javaMenu Java::buildMenu
  108.  
  109. set Java::commentCharacters(Paragraph) [list "/**" " */" " * "]
  110.  
  111. # If this package exists, add the headers menu
  112. if {[alpha::package exists searchPaths]} {
  113.     menu::buildProc javaSearchPath {mode::rebuildSearchPathMenu javaSearchPath}
  114.     menu::insert javaMenu submenu end javaSearchPath
  115. }
  116.  
  117. menu::buildSome javaMenu
  118.  
  119. proc Java::MenuProc {menu item} {
  120.     eval Java::$item
  121. }
  122.  
  123. proc Java::electricLeft {args} {
  124.     uplevel 1 C++::electricLeft $args
  125. }
  126.  
  127. proc Java::correctIndentation {args} {
  128.     uplevel 1 C++::correctIndentation $args
  129. }
  130. proc Java::indentLine {args} {
  131.     uplevel 1 C++::indentLine $args
  132. }
  133.  
  134. proc Java::newJavadocComment {} {
  135.     elec::Insertion "/**\r * •comment body•\r */\r••"
  136. }
  137.  
  138. proc Java::editProjects {} {
  139.     dialog::editOneOfMany "Edit or create a new Java project" \
  140.       JavaProject JavaProjects Java_projectStore project
  141. }
  142.  
  143. # Launches Java Compiler
  144. proc Java::switchToCompiler {} {
  145.     global javacompilerSig
  146.     app::launchAnyOfThese javc javacompilerSig "Please locate the Java compiler:"
  147.     switchTo '$javacompilerSig'
  148. }
  149.  
  150. # Sends the window to the compiler.
  151. proc Java::compileFile {} {
  152.     global showJavacompilerLog classSearchPath JavaProjects
  153.     set path [win::StripCount [win::Current]]
  154.  
  155.     if {[winDirty]} {
  156.     switch -- [askyesno -c "Save '[file tail $path]'?"] {
  157.         "yes" {
  158.         save
  159.         # Get path again, in case it was Untitled before.
  160.         set path [win::StripCount [win::Current]]
  161.         }
  162.         "no" {
  163.         if {![file exists $path]} {
  164.             alertnote "Can't send window to compiler."
  165.             return
  166.         }
  167.         }
  168.         "cancel" {return}
  169.     }
  170.     }
  171.     # Experimental code which will allow you to compile into a hierarchy
  172.     # using javac's ability to find related class files in multiple packages
  173.     # automatically.  This is needed for any project which contains files
  174.     # in more than one directory.
  175.  
  176.     # Of course we only want to do this if the current file is in the 
  177.     # compilation path given.  Else we'll assume it's a standalone file.
  178.     set compileFrom ""
  179.     set placeClasses ""
  180.  
  181.     # We check automatically whether a given file is in a project
  182.     # by examining whether the path matches.
  183.     foreach proj [array names JavaProjects] {
  184.     array set tmp $JavaProjects($proj)
  185.     if {$tmp(compileFromThisFolder) != "" \
  186.       && [file::pathStartsWith $path $tmp(compileFromThisFolder)]} {
  187.         set compileFrom $tmp(compileFromThisFolder)
  188.         set placeClasses $tmp(placeClassesHere)
  189.         break
  190.     }
  191.     }
  192.     
  193.     if {$placeClasses != ""} {
  194.     app::runScript javacompiler "Java compiler" \
  195.       $path 0 $showJavacompilerLog \
  196.       "-d $placeClasses -classpath [join $classSearchPath {;}]" \
  197.       $compileFrom
  198.     } else {
  199.     app::runScript javacompiler "Java compiler" \
  200.       $path 0 $showJavacompilerLog "-classpath [join $classSearchPath {;}]" \
  201.       $compileFrom
  202.     }
  203. }
  204.  
  205. # Opens a HTML file corresponding to a java file in the Applet Viewer.
  206. # If there is a file some_applet.html in the same folder as some_applet.java
  207. # it is sent. Otherwise the user is asked to select a HTML file.
  208. # This file is remembered throughout this session with Alpha.
  209. proc Java::viewApplet {} {
  210.     global javaAppletFile javaviewerSig
  211.     set name [win::StripCount [win::Current]]
  212.     set dir [file dirname $name]
  213.     set root [file rootname [file tail $name]]
  214.     set path [file join $dir $root.html]
  215.     if {[info exists javaAppletFile($name)] && [file exists $javaAppletFile($name)]} {
  216.     set path $javaAppletFile($name)
  217.     } elseif {![file exists $path]} {
  218.     set path [getfile "Please locate HTML file for applet."]
  219.     set javaAppletFile($name) $path
  220.     }
  221.     app::launchAnyOfThese [list AppV WARZ] javaviewerSig "Please locate the Applet viewer:"
  222.     sendOpenEvent noReply '$javaviewerSig' $path
  223.     switchTo '$javaviewerSig'
  224. }
  225.  
  226. proc Java::MarkFile {} {
  227.     Java::MarkFile2 1
  228. }
  229.  
  230. proc Java::parseFuncs {} {
  231.     Java::MarkFile2 0
  232. }
  233.  
  234.  
  235. # My version of    Java::MarkFile. First revision, April 1996.
  236. # Jim Menard, jimm@io.com
  237. # Improved by Vince: both start and end position of embedded classes are
  238. # stored, so if we order methods/sub-classes randomly, we still mark 
  239. # things properly.
  240. proc Java::MarkFile2 {marking} {
  241.     # Sorry, but globals are a lot easier than using "upvar" in subroutines
  242.     global markArray
  243.     global classInfo
  244.     
  245.     catch {unset markArray}
  246.     set classInfo ""
  247.     
  248.     # Look for class definitions first
  249.     set markExpr "^\[ \t\]*(\[A-Za-z_\]\[A-Za-z0-9_\]*\[ \t\]+)*class\[ \t\]+\[A-Za-z_\]\[A-Za-z0-9_\]*\[ \t\r\](\[A-Za-z_\]\[A-Za-z0-9_.,\]*\[ \t\]+)*\{"
  250.     set wordExpr "class\[ \t\]+(\[A-Za-z_\]\[A-Za-z0-9_\]*)"
  251.     set commands {
  252.     set markArray([concat $word "class"]) $markPos
  253.     # Remember mark    position and name separately so    we can call
  254.     # Java::getClassFromPos() later.
  255.     lappend    classInfo [list $word $markPos $endPos]
  256.     }
  257.     Java::searchAndDestroy $markExpr $wordExpr $commands 0
  258.     
  259.     # The following regular expression is overly restrictive. After the open
  260.     # paren, I disallow semicolons. That avoids finding lines like
  261.     # throw new FooException(arg);
  262.     # which is good, but unfortunately also avoids finding lines like
  263.     # public int foo(arg) // comment with semi;
  264.     #
  265.     # It doesn't find constructors without a "public", "private", or other phrase
  266.     # before the method name since it requires at least one word before the
  267.     # method name. They are special-cased below. I did that so function calls,
  268.     # "if" statements, and the like wouldn't be found.
  269.     set markExpr "^\[ \t\]*(\[A-Za-z_\]\[A-Za-z0-9_\]*(\[ \t\]*\\\[\\])*\[ \t\]+)+\[A-Za-z_\]\[A-Za-z0-9_\]*\[ \t\r\]*\\(\[^;\]+$"
  270.     set wordExpr "(\[A-Za-z_\]\[A-Za-z0-9_\]*)\[ \t\]*\\("
  271.     set commands {
  272.     if {$className == $word} {
  273.         set markArray([concat $className "constructor"]) $markPos
  274.     } else {
  275.         set markArray(${className}::$word) $markPos
  276.     }
  277.     }
  278.     Java::searchAndDestroy $markExpr $wordExpr $commands 1
  279.     
  280.     # One more time; let's go back for constructors with no modifiers.
  281.     set markExpr "^\[ \t\]*\[A-Za-z\]\[A-Za-z0-9_\]*\[ \t\r\]*\\(\[^;\]+$"
  282.     set wordExpr "(\[A-Za-z\]\[A-Za-z0-9_\]*)\[ \t\]*\\("
  283.     set commands {
  284.     if {$className == $word} {
  285.         set markArray([concat $className "constructor"]) [lineStart [expr $start - 1]]
  286.     }
  287.     }
  288.     Java::searchAndDestroy $markExpr $wordExpr $commands 1
  289.     
  290.     if {[info exists markArray]} {
  291.     foreach    f [lsort -ignore [array    names markArray]] {
  292.         set next [nextLineStart $markArray($f)]
  293.         
  294.         if {[regexp {.*(::if)$} $f] == 0} {
  295.         if {[string length $f] > 35} { 
  296.             set ff "[string range $f 0 31]..." 
  297.         } else {
  298.             set ff $f
  299.         }
  300.         if {$marking} {
  301.             setNamedMark "$ff" "$markArray($f)" $next $next
  302.         } else {
  303.             lappend parse $ff $next
  304.         }
  305.         }
  306.     }
  307.     }
  308.     if {!$marking} {return $parse}
  309. }
  310.  
  311. # Start    at top of file and find    text that matches markExpr. Clean it up    and
  312. # use wordExpr to find the word    we want. Execute commands.
  313. proc Java::searchAndDestroy {markExpr wordExpr commands needClassName} {
  314.     global markArray classInfo allowMultipleClassesPerFile
  315.     if {!$needClassName} {
  316.     # If the variable getEnd exists, we want to find the range that
  317.     # this class/function encompasses.  If this flag is set, we may
  318.     # have multiple classes, and hence cannot assume the first class
  319.     # we find extends to the end of the file.
  320.     set getEnd $allowMultipleClassesPerFile
  321.     }
  322.     
  323.     set pos [minPos]
  324.     
  325.     while {![catch {search -s -f 1 -r 1 -m 0 -i 0 -- "$markExpr" $pos} res]} {
  326.     set start [lindex $res 0]
  327.     set end    [pos::math [lindex $res 1] + 1]
  328.     if {[pos::compare $end > [maxPos]]} {
  329.         set end [maxPos]
  330.     }
  331.     set thistext [getText $start $end]
  332.     if {$needClassName} {
  333.         set className [Java::getClassFromPos $start $classInfo]
  334.     }
  335.     # regexp doesn't like carriage returns or tabs
  336.     regsub -all "\[\n\r\t\]" $thistext " " thistext
  337.     # If the open paren was    the last character on the line,
  338.     # the selected text included the last carriage return as well.
  339.     # Trim this off    now that it is changed into a space.
  340.     set thistext [string trimright $thistext]
  341.     if {[regexp -- $wordExpr $thistext dummy word]} {
  342.         set markPos [lineStart [pos::math $start - 1]]
  343.         if {[info exists getEnd]} {
  344.         if {$getEnd} {
  345.             set endPos [lindex [search -s -f 1 -m 0 -i 0 -- "\{" $markPos] 1]
  346.             set endPos [matchIt "\{" $endPos]
  347.         } else {
  348.             # little efficiency thing: the first class we find, we know
  349.             # extends to the end of the file, so we don't bother doing
  350.             # its 'matchIt' because it is very time-consuming.
  351.             set endPos [maxPos]
  352.             set getEnd 1
  353.         }
  354.         }
  355.         eval $commands
  356.     }
  357.     set pos    $end
  358.     }
  359. }
  360.  
  361. # Given    a file position, find the class    definition in which it resides.
  362. # There's got to be an easier way than passing two separate lists. 
  363. # I tried fooling
  364. # around with markArray(), but don't know Tcl well enough to use it instead.
  365. proc Java::getClassFromPos {pos classInfo} {
  366.     set nClasses [llength $classInfo]
  367.     for {set i [expr {$nClasses - 1}]} {$i >= 0} {incr i -1} {
  368.     set range [lindex $classInfo $i]
  369.     if {[pos::compare [lindex $range 1] <= $pos] && [pos::compare [lindex $range 2] >= $pos]} {
  370.         return [lindex $range 0]
  371.     }
  372.     }
  373.     return ""
  374. }
  375.